package com.example.sup.config;

import com.example.sup.constants.TaskStateEnum;
import com.example.sup.entity.TaskManagement;
import com.example.sup.service.TaskManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;

/**
 * @ClassName SupSchedulingConfigurerOptimize
 * @Description {TODO}
 * @Author 李哲
 * @Date 11:45 2024/8/1
 * @Version 1.0
 */
@Configuration
@Slf4j
public class SupSchedulingConfigurerOptimize implements SchedulingConfigurer {
    @Resource
    private TaskManagementService iTaskManagementService;


    private ScheduledTaskRegistrar taskRegistrar;

    //保存我们正在运行的任务的future
    Map<Integer, ScheduledFuture> scheduledFutureMap = new HashMap<>();

    //在我们sb应用启动，spring的schedul模块自动调用下面
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        //1.设置使用多线程进行任务调度  设置大小30的线程池
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(30));
        this.taskRegistrar = taskRegistrar;
        //2.启动任务
        List<TaskManagement> taskManagementList = iTaskManagementService.list();
        taskManagementList.forEach(taskManagement -> {
            //1.定时任务需要执行的操作
            Runnable runnable = new Runnable(){
                @Override
                public void run() {
                    //TODO 真实情况是要要发送指令给电力设备，执行对应的操作（断电，开电，开空调....）,我们这里使用输出来模拟
                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //设置日期格式
                    System.out.println("hello world " + df.format(new Date()));
                }
            };
            //2.根据定时任务执行的操作和cron表达式构建CronTask
            CronTask cronTask = new CronTask(runnable,taskManagement.getCron());
            //3.启动定时任务
            if(taskManagement.getState().equals(TaskStateEnum.ON.getCode())) {
                ScheduledFuture<?> scheduledFuture = taskRegistrar.getScheduler().
                        schedule(runnable, cronTask.getTrigger());
                //将当前正在执行的任务保存起来
//                scheduledFutureList.add(scheduledFuture);
                scheduledFutureMap.put(taskManagement.getTaskId(),scheduledFuture);
            }
        });

    }
    /**
     * 更新定时任务
     * @param taskManagement
     */
    public  void refresh(TaskManagement taskManagement) {
        //1.当前任务如果已经在执行，则先取消,然后从启动列表移除  scheduledFuture.cancel(false);
        if(scheduledFutureMap.containsKey(taskManagement.getTaskId())){
            ScheduledFuture scheduledFuture = scheduledFutureMap.get(taskManagement.getTaskId());
            //1.1.取消任务
            boolean result = scheduledFuture.cancel(false);
            //1.2.从启动列表中删除
            if(result){
                log.info("任务：{},已取消",taskManagement.getTaskId());
                scheduledFutureMap.remove(taskManagement.getTaskId());
            }
        }
        //2.根据任务状态开关任务
        if(taskManagement.getState().equals(TaskStateEnum.ON.getCode())){
            //1.定时任务需要执行的操作
            Runnable runnable = new Runnable(){
                @Override
                public void run() {
                    //TODO 真实情况是要要发送指令给电力设备，执行对应的操作（断电，开电，开空调....）,我们这里使用输出来模拟
                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //设置日期格式
                    System.out.println("早上6点开灯任务启动" + df.format(new Date()));
                }
            };
            //2.根据定时任务执行的操作和cron表达式构建CronTask
            CronTask cronTask = new CronTask(runnable,taskManagement.getCron());
            //3.启动定时任务
            if(taskManagement.getState().equals(TaskStateEnum.ON.getCode())) {
                log.info("任务：{},重新启动.....",taskManagement.getTaskId());
                ScheduledFuture<?> scheduledFuture = taskRegistrar.getScheduler().schedule(runnable, cronTask.getTrigger());
                //将当前正在执行的任务保存起来
//                scheduledFutureList.add(scheduledFuture);
                scheduledFutureMap.put(taskManagement.getTaskId(),scheduledFuture);
            }
        }

    }

}
